/* 图片上传组件
 * value 绑定的值
 */
Vue.component('dt-upload', {
    template: `<el-upload list-type="picture-card" :action="action"
                    accept="image/*"
                    :show-file-list="false" 
                    :http-request="handleUpload"
                    :before-upload="handleBefore">
                    <div style="display:flex;justify-content:center;align-items:center;width:100%;height:100%">
                        <img v-if="value" :src="imgsrc" style="margin:auto;max-width:100%;max-height:100%" />
                        <i v-else-if="!uploadFlag" class="el-icon-plus"></i>
                        <el-progress v-if="uploadFlag" type="circle"
                            :width="126" 
                            :height="126"
                            :percentage="uploadPercent"
                            style="position:absolute;top:0;left:0;margin:10px;">
                        </el-progress>
                    </div>
                </el-upload>`,
    props: {
        value: {
            type: String,
            default: null
        },
        action: {
            type: String,
            default: '/upload',
        }
    },
    data: function () {
        return {
            imgsrc: '',
            uploadFlag: false,
            uploadPercent: 0
        }
    },
    methods: {
        //上传前检查
        handleBefore(file) {
            const isImg = /^image\/\w+$/i.test(file.type)
            if (!isImg) {
                this.$message.error('只能上传 JPG、PNG、GIF 格式!')
                return false
            }
            return true;
        },
        //上传文件
        handleUpload(item) {
            let _this = this;
            const formData = new FormData();
            formData.append("file", item.file);
            AxiosAjax({
                method: 'file',
                url: `${_this.action}`,
                data: formData,
                progress: function (event) {
                    _this.handleProcess(event, item.file);
                },
                success: function (res) {
                    _this.handleSuccess(res.data, item.file);
                }
            });
        },
        //上传成功
        handleSuccess(res, file) {
            this.uploadFlag = false;
            this.uploadPercent = 0;
            // 拼接得到图片 url
            const imageUrl = res[0].filePath;
            this.imgsrc = baseApi + imageUrl;
            // 触发事件 input，父组件会修改绑定的 value 值
            this.$emit('input', imageUrl)
        },
        //上传进度
        handleProcess(event, file) {
            this.uploadFlag = true;
            this.uploadPercent = Math.abs((event.loaded / event.total * 100).toFixed(0));
        }
    },
    watch: {
        value: function (newVal) {
            if (newVal) {
                this.imgsrc = baseApi + newVal;
            }
        }
    }
});

/* 文本域上传组件
 * value 绑定的值
 * placeholder 显示文本
 * width 预览图片的宽度，支持px,%单位
 * height 预览图片的高度，支持px,%单位
 * fit 图片显示类型 fill / contain / cover / none / scale-down
 * size 上传大小 单位KB 默认1024KB
 * water 是否加水印 1加水印0不加 默认0
 * thumb 生成缩略图 1生成0不生成 默认0
 * exts 允许上传的类型 多个类型用逗号分开，例如 jpg,png,gif
 * action 上传地址
 */
Vue.component('dt-upload-text', {
    template: `<div class="input-upload">
                    <div class="up-control">
                        <el-input :placeholder="placeholder" v-model="filePath"></el-input>
                        <el-upload :disabled="imgUrlUploading"
                                    :action="action"
                                    :show-file-list="false"
								    :http-request="handleUpload"
                                    :before-upload="handleBefore"
                                    :on-error="handleError">
                            <el-button type="primary" :loading="imgUrlUploading">{{imgUrlProgress}}</el-button>
                        </el-upload>
                    </div>
                    <div v-if="isImg" class="img-preview">
                        <el-image v-if="imgSrc" :style="'width:'+ width+';'+'height:'+height+';'"
                                    :src="imgSrc"
                                    :fit="fit"
                                    :preview-src-list="new Array(imgSrc)">
                        </el-image>
                    </div>
                </div>`,
    props: {
        value: String,
        placeholder: String,
        width: {
            type: String,
            default: '40%',
        },
        height: {
            type: String,
            default: '30%',
        },
        fit: {
            type: String,
            default: 'contain',
        },
        size: {
            type: Number,
            default: 1024,
        },
        water: {
            type: Number,
            default: 0,
        },
        thumb: {
            type: Number,
            default: 0,
        },
        exts: {
            type: String,
            default: 'jpg,jpeg,png,gif,bmp',
        },
        action: {
            type: String,
            default: '/upload',
        }
    },
    data: function () {
        return {
            filePath: null,
            imgSrc: null,
            imgUrlProgress: '浏览...',
            imgUrlUploading: false,
            isImg: false,
        }
    },
    methods: {
        //上传前检查
        handleBefore(file) {
            let _this = this;
            let isUploadExt = false;
            let fileName = file.name;
            //检查是否合法的扩展名
            if (fileName.lastIndexOf(".") === -1) {
                _this.$message.error('不支持的上传类型!');
                return false;
            }
            let ext = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase();
            let extArr = _this.exts.toLowerCase().split(',');//允许的扩展名数组
            let extObj = extArr.find(val => val == ext);
            if (!extObj) {
                _this.$message.error('不支持的上传类型!');
                return false;
            }
            //计算文件大小
            let fileSize = parseFloat(file.size / 1024);//转换成KB
            if (fileSize > _this.size) {
                _this.$message.error(`文件大小不能超过${_this.size}KB!`);
                return false;
            }
            //检查是否是图片，如果是图片要显示出来
            _this.isImg = _this.verifyImage(fileName);
            _this.imgUrlUploading = true;
            return true;
        },
        //上传文件
        handleUpload(item) {
            let _this = this;
            const formData = new FormData();
            formData.append("file", item.file);
            AxiosAjax({
                method: 'file',
                url: `${_this.action}?water=${_this.water}&thumb=${_this.thumb}`,
                data: formData,
                progress: function (event) {
                    _this.handleProcess(event, item.file);
                },
                success: function (res) {
                    _this.handleSuccess(res.data, item.file);
                }
            });
        },
        //上传成功
        handleSuccess(res, file) {
            this.imgUrlProgress = "浏览...";
            this.imgUrlUploading = false;
            this.filePath = res[0].filePath;
            
        },
        //上传进度
        handleProcess(event, file) {
            this.imgUrlProgress = (event.loaded / event.total * 100).toFixed(0) + '%';
        },
        //上传失败
        handleError(err, file, fileList) {
            this.imgUrlUploading = false;
            this.$message.error(err.message);
        },
        //验证是否是图片
        verifyImage(src) {
            let _this = this;
            if (!src) return false;
            let imgExtArr = ['jpg', 'jpeg', 'png', 'gif'];
            let startIndex = src.lastIndexOf(".");
            if (startIndex === -1) {
                return false;
            }
            let ext = src.substring(startIndex + 1, src.length).toLowerCase();
            let extObj = imgExtArr.find(val => val == ext);
            if (extObj) return true;
            return false;
        },
        //给预览图赋值
        setImage(src) {
            let _this = this;
            //如果是图片则赋值给预览图
            _this.isImg = _this.verifyImage(src);
            if (_this.isImg) {
                if (src.startsWith("/")) {
                    _this.imgSrc = baseApi + src;
                } else {
                    _this.imgSrc = src;
                }
            }
        }
    },
    mounted: function () {
        if (this.value) {
            this.filePath = this.value;
            this.setImage(this.value);
        }
    },
    watch: {
        value(newVal) {
            this.filePath = newVal;
            this.setImage(newVal);
        },
        filePath: function (newVal) {
            this.setImage(newVal);
            this.$emit('input', newVal);
        }
    }
});

/*相册组件
 * value 绑定的数组
 * action 上传地址
 * limit 最大允许上传个数，0不限制
 * size 上传大小 单位KB 默认2048KB
 * water 是否加水印 1加0不加 默认1
 * thumb 生成缩略图 1生成0不生成 默认1
 * exts 允许上传的类型 多个类型用逗号分开，例如 jpg,png,gif
 */
Vue.component('dt-upload-album', {
    template: `<div class="album-box">
                <el-upload class="list-bin" list-type="picture-card" multiple :action="action"
                    accept="image/*"
                    :http-request="handleUpload"
                    :before-upload="handleBefore"
                    :on-error="handleError"
                    :on-exceed="handleExceed" 
                    :limit="limit"
                    :file-list="listData"
                    :show-file-list="false" 
                    :auto-upload="true">
                    <i slot="default" class="el-icon-plus"></i>
                </el-upload>
                <div class="list-box" v-for="(file,index) in listData" :key="index">
                    <div class="img-box"><img :src="file.url" /></div>
                    <span class="text-box" v-if="file.remark">{{file.remark}}</span>
                    <div class="tools-box">
                        <span class="icon" @click="handleRemove(file,index)">
                            <i class="el-icon-delete"></i>
                        </span>
                        <span class="icon" @click="handlePreview(file,index)">
                            <i class="el-icon-zoom-in"></i>
                        </span>
                        <span class="icon" @click="handleRemark(file,index)">
                            <i class="el-icon-edit"></i>
                        </span>
                    </div>
                    <el-progress v-if="file.progressFlag" type="circle" :width="118" :height="118" :percentage="file.progressPercent"></el-progress>
                </div>
                <el-dialog :modal="false" title="图片预览" :visible.sync="showImgDialog">
                    <img width="100%" :src="showImgUrl" />
                </el-dialog>
                </div>`,
    props: {
        value: {
            type: Array,
            default:[]
        },
        action: {
            type: String,
            default: '/upload',
        },
        size: {
            type: Number,
            default: 2048,
        },
        limit: {
            type: Number,
            default: 0
        },
        water: {
            type: Number,
            default: 1
        },
        thumb: {
            type: Number,
            default: 1
        },
    },
    data: function () {
        return {
            listData: [],
            showImgDialog: false,
            showImgUrl: null,
        }
    },
    methods: {
        //上传前检查
        handleBefore(file) {
            let _this = this;
            const isImg = /^image\/\w+$/i.test(file.type)
            if (!isImg) {
                this.$message.error('只能上传 JPG、PNG、GIF 格式')
                return false
            }
            let fileSize = parseFloat(file.size / 1024);//字节转为KB
            if (fileSize > _this.size) {
                _this.$message.error(`图片大小不能超过${_this.size}KB`);
                return false;
            }
            file.url = URL.createObjectURL(file);
            _this.listData.push(file);
            return true;
        },
        //上传文件
        handleUpload(item) {
            let _this = this;
            const formData = new FormData();
            formData.append("file", item.file);
            AxiosAjax({
                method: 'file',
                url: `${_this.action}?water=${_this.water}&thumb=${_this.thumb}`,
                data: formData,
                progress: function (event) {
                    _this.handleProcess(event, item.file);
                },
                success: function (res) {
                    _this.handleSuccess(res.data, item.file);
                }
            });
        },
        //上传成功
        handleSuccess(res, file) {
            let _this = this;
            let index = -1;
            _this.listData.forEach(function (item, i) {
                if (item === file) {
                    index = i;
                }
            });
            file.id = 0;
            file.url = baseApi + res[0].thumbPath;
            file.progressFlag = false;
            file.progressPercent = 0;
            file.thumbPath = res[0].thumbPath[0];
            file.originalPath = res[0].filePath;
            file.remark = null;
            if (index != -1) {
                _this.listData.splice(index, 1, file);
                _this.$emit('input', _this.listData);
            }
        },
        //上传进度
        handleProcess(event, file) {
            let _this = this;
            let index = -1;
            _this.listData.forEach(function (item,i) {
                if (item == file) {
                    index = i;
                }
            });
            file.progressFlag = true;
            file.progressPercent = Math.abs((event.loaded / event.total * 100).toFixed(0));
            if (index != -1) {
                _this.listData.splice(index, 1, file);
            }
        },
        //超出限制
        handleExceed(files, fileList) {
            this.$message.error("错误：超出上传最大限制数量")
        },
        //上传失败
        handleError(err, file, fileList) {
            this.$message.error(err.message);
        },
        //删除文件
        handleRemove(file, i) {
            let _parent = this; //父页面
            let _this = this; //当前页面
            //判断是否有父窗体
            if (typeof (parent.vm) != "undefined") {
                _parent = parent.vm;
            }
            _parent.$confirm('确认要删除该图片吗？', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                _this.listData.splice(i, 1);
                _this.$emit('input', _this.listData);
            }).catch((meg) => console.log(meg));
        },
        //查看图片
        handlePreview(file, i) {
            this.showImgUrl = baseApi + file.originalPath;
            this.showImgDialog = true;
        },
        //修改备注
        handleRemark(file, i) {
            let _parent = this; //父页面
            let _this = this; //当前页面
            //判断是否有父窗体
            if (typeof (parent.vm) != "undefined") {
                _parent = parent.vm;
            }
            _parent.$prompt("请输入备注：", "图片描述", {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                inputValue: file.remark,
                closeOnClickModal: false
            }).then(({ value }) => {
                file.remark = value;
                _this.listData.splice(i, 1, file);
                _this.$emit('input', _this.listData);
            }).catch(() => { })
        },
    },
    watch: {
        value: function (newVal) {
            let _this = this;
            if (newVal.length > 0 && _this.listData.length == 0) {
                this.$nextTick(() => {
                    _this.listData = newVal;
                });
            }
        },
        listData: function (newVal) {
            let _this = this;
            if (newVal) {
                newVal.forEach(val => {
                    if (val.url && !val.url.indexOf('http') == 0 && !val.url.indexOf('blob:http') == 0) {
                        val.url = baseApi + val.url;
                    }
                });
            }
        }
    }
});

/* 附件上传组件
 * value 绑定的值
 * placeholder 显示文本
 * limit 最大允许上传个数
 * size 上传大小 单位KB 默认5MB
 * exts 允许上传的类型 多个类型用逗号分开，例如 jpg,png,gif
 * action 上传地址
 */
Vue.component('dt-upload-attach', {
    template: `<div class="attach-box">
                <el-upload class="list-btn" multiple list-type="picture" :action="action"
                    :http-request="handleUpload"
                    :before-upload="handleBefore"
                    :on-error="handleError"
                    :on-exceed="handleExceed" 
                    :limit="limit"
                    :file-list="listData"
                    :show-file-list="false" 
                    :auto-upload="true">
                    <el-button size="medium" type="primary">{{placeholder}}</el-button>
                    <div slot="tip" class="el-upload__tip" v-if="limit>0">只能上传 {{exts}} 文件，且不超过 {{size}}KB，最多可添加 {{limit}} 个文件。</div>
                    <div slot="tip" class="el-upload__tip" v-else>只能上传 {{exts}} 文件，且不超过 {{size}}KB。</div>
                </el-upload>
                <div class="list-wrap">
                    <div class="list-box" v-for="(file,index) in listData" :key="index">
                        <div class="img-box">
                            <span v-if="file.fileExt">{{file.fileExt.toUpperCase()}}</span>
                            <i class="el-icon-loading" v-else></i>
                        </div>
                        <div class="info-box">
                            <h3>{{file.fileName}}</h3>
                            <dl>
                                <dt>
                                    <span v-if="file.fileSize">大小 {{handleFileSize(file.fileSize)}}</span>
                                    <span>下载 {{file.downCount}}次</span>
                                </dt>
                                <dd>
                                    <span @click="handleDownload(file,index)"><i class="el-icon-download"></i></span>
                                    <span @click="handleUpdate(file,index)"><i class="el-icon-edit"></i></span>
                                </dd>
                            </dl>
                        </div>
                        <div class="close" @click="handleRemove(file,index)"><i class="el-icon-close"></i></div>
                        <el-progress v-if="file.progressFlag" :show-text="false" :percentage="file.progressPercent"></el-progress>
                    </div>
                </div>
            </div>`,
    props: {
        value: {
            type: Array,
            default: []
        },
        placeholder: {
            type: String,
            default: '点击上传',
        },
        limit: {
            type: Number,
            default: 0
        },
        size: {
            type: Number,
            default: 5120,
        },
        exts: {
            type: String,
            default: 'jpg,jpeg,png,gif,bmp',
        },
        action: {
            type: String,
            default: '/upload',
        }
    },
    data: function () {
        return {
            listData: [],
        }
    },
    methods: {
        //上传前检查
        handleBefore(file) {
            let _this = this;
            let isUploadExt = false;
            let fileName = file.name;
            let ext = "";//扩展名
            //获取最后一个.的位置
            let extIndex = fileName.lastIndexOf(".");
            if (extIndex === -1) {
                _this.$message.error('错误：不支持的上传类型');
                return false;
            }
            ext = fileName.substring(extIndex + 1, fileName.length).toLowerCase();
            let extArr = _this.exts.toLowerCase().split(',');//允许的扩展名数组
            //判断是否包含该扩展名
            extArr.forEach(item => {
                if (item === ext) {
                    isUploadExt = true;
                }
            })
            if (!isUploadExt) {
                _this.$message.error('错误：不支持的上传类型');
                return false;
            }
            let fileSize = parseFloat(file.size / 1024);//转换成KB
            if (fileSize > _this.size) {
                _this.$message.error(`错误：文件大小不能超过${_this.size}KB`);
                return false;
            }
            file.url = URL.createObjectURL(file);
            file.fileName = file.name;
            file.downCount = 0;
            _this.listData.push(file);
            return true;
        },
        //上传文件
        handleUpload(item) {
            let _this = this;
            const formData = new FormData();
            formData.append("file", item.file);
            AxiosAjax({
                method: 'file',
                url: `${_this.action}?water=${_this.water}&thumb=${_this.thumb}`,
                data: formData,
                progress: function (event) {
                    _this.handleProcess(event, item.file);
                },
                success: function (res) {
                    _this.handleSuccess(res.data, item.file);
                }
            });
        },
        //上传进度
        handleProcess(event, file) {
            let _this = this;
            let index = -1;
            _this.listData.forEach(function (item, i) {
                if (item == file) {
                    index = i;
                }
            });
            file.progressFlag = true;
            file.progressPercent = Math.abs((event.loaded / event.total * 100).toFixed(0));
            if (index != -1) {
                _this.listData.splice(index, 1, file);
            }
        },
        //超出文件限制
        handleExceed(files, fileList) {
            this.$message.error("错误：超出上传最大限制数量")
        },
        //上传成功
        handleSuccess(res, file) {
            let _this = this;
            let index = -1;
            _this.listData.forEach(function (item, i) {
                if (item === file) {
                    index = i;
                }
            });
            file.id = 0;
            file.url = baseApi + res[0].filePath;
            file.progressFlag = false;
            file.progressPercent = 0;
            file.fileName = res[0].fileName;
            file.filePath = res[0].filePath;
            file.fileSize = res[0].fileSize;
            file.fileExt = res[0].fileExt;
            file.downCount = 0;
            if (index != -1) {
                _this.listData.splice(index, 1, file);
                _this.$emit('input', _this.listData);
            }
        },
        //修改文件名
        handleUpdate(file, i) {
            let _parent = this; //父页面
            let _this = this; //当前页面
            //判断是否有父窗体
            if (typeof (parent.vm) != "undefined") {
                _parent = parent.vm;
            }
            _parent.$prompt("请输入新文件名：", "修改名称", {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                inputValue: file.name,
                closeOnClickModal: false
            }).then(({ value }) => {
                if (!value) {
                    return false;
                }
                file.fileName = value;
                _this.listData.splice(i, 1, file);
                _this.$emit('input', _this.listData);
            }).catch(() => { })
        },
        //下载文件
        handleDownload(file, i) {
            window.location.href = file.url;
        },
        //删除文件
        handleRemove(file, i) {
            let _parent = this; //父页面
            let _this = this; //当前页面
            //判断是否有父窗体
            if (typeof (parent.vm) != "undefined") {
                _parent = parent.vm;
            }
            _parent.$confirm('确认要删除文件吗？', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                _this.listData.splice(i, 1);
                _this.$emit('input', _this.listData);
            }).catch((meg) => console.log(meg));
        },
        //上传失败
        handleError(err, file, fileList) {
            this.$message.error(err.message);
        },
        //转换大小
        handleFileSize(val) {
            if (val < 1024.00)
                return val + "B";
            else if (val >= 1024.00 && val < 1048576)
                return parseInt(val / 1024.00) + "KB";
            else if (val >= 1048576 && val < 1073741824)
                return (val / 1024.00 / 1024.00).toFixed(2) + "MB";
            else if (val >= 1073741824)
                return (val / 1024.00 / 1024.00 / 1024.00).toFixed(2) + "GB";
        },
    },
    watch: {
        value: function (newVal) {
            let _this = this;
            if (newVal.length > 0 && _this.listData && _this.listData.length == 0) {
                this.$nextTick(() => {
                    _this.listData = newVal;
                });
            }
        },
        listData: function (newVal) {
            let _this = this;
            if (newVal) {
                newVal.forEach(val => {
                    if (val.url && !val.url.indexOf('http') == 0 && !val.url.indexOf('blob:http') == 0) {
                        val.url = baseApi + val.url;
                    }
                });
            }
        }
    }
});
